﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Threading;
using log4net;
using YEA.Utilities.Service.Controller;

namespace YEA.Monitor.LogService.States
{
    public class RecoveryState : ServiceStateBase, IServiceState
    {
        protected bool isStopped;
        internal RunningState RunningState;
        internal Diagnostic Diagnosis { private get; set; }

        public ILog Logger { get; set; }

        public RecoveryState( RunningState state)
        {
            RunningState = state;
            isStopped = false;
        }

        public void Start()
        {
            isStopped = false;
            switch (Diagnosis)
            {
                case Diagnostic.DatabaseError :
                    while ( isStopped || !checkDBConnectivity())
                    {
                        Thread.Sleep(1000);
                    }
                    SendStatusEvent(new StateEventArgs { state = StateEvent.Recovered });
                    break;
                case Diagnostic.MessageBusUnavailable :
                    //in async mode, there's now way to passively test the connection, all we can do unmount all connections wait and try again.
                    RunningState.Stop();
                    Thread.Sleep(10000);
                    while (isStopped )
                    {
                        Thread.Sleep(1000);
                    }
                    SendStatusEvent(new StateEventArgs { state = StateEvent.Recovered });
                    break;

                default:
                case Diagnostic.Unknown :
                    //nothing to do about this one, we need to see if this is a continuous stream of exceptions and then raise the 
                    //diagnostic level to fatal.
                    while ( isStopped )
                    {
                        Thread.Sleep(1000);
                    }
                    SendStatusEvent(new StateEventArgs { state = StateEvent.Recovered });
                    break;
                case Diagnostic.FatalForUnknownReasons :
                    Logger.Fatal("Can't recover from error, stop service down");
                    SendStatusEvent(new StateEventArgs { state = StateEvent.Stopped });
                    break;
            }
        }

        private bool checkDBConnectivity()
        {
            //Todo: check db connectivity by calling the SqlConnection.Open() method.
            return true;
        }

        public void Stop()
        {
            isStopped = true;
        }

        public void Pause()
        {
            Stop();
        }

        public void Continue()
        {
            isStopped = false;
        }

        public void Dispose()
        {
        }
    }
}
